TypeScriptã®é«åºŠãªåæäœã®åãè§£ãæŸã¡ãŸãããããã®ã¬ã€ãã§ã¯ãå ç¢ã§ã¹ã±ãŒã©ãã«ãä¿å®æ§ã®é«ãã°ããŒãã«ãªãœãããŠã§ã¢ã·ã¹ãã ãæ§ç¯ããããã«ãæ¡ä»¶ä»ãåããããåãåæšè«ãªã©ãæ¢ããŸãã
åæäœïŒå ç¢ãªãœãããŠã§ã¢èšèšã®ããã®é«åºŠãªå倿ãã¯ããã¯
é²åãç¶ããçŸä»£ã®ãœãããŠã§ã¢éçºã«ãããŠãåã·ã¹ãã ã¯ãå埩åããããä¿å®æ§ãé«ããã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããäžã§ãŸããŸãéèŠãªåœ¹å²ãæãããŠããŸããç¹ã«TypeScriptã¯ãJavaScriptã匷åãªéçåä»ãæ©èœã§æ¡åŒµããæ¯é çãªåãšããŠå°é ããŸãããå€ãã®éçºè ã¯åºæ¬çãªå宣èšã«ã¯æ £ããŠããŸãããTypeScriptã®çã®åã¯ããã®é«åºŠãªåæäœæ©èœã«ãããŸããããã¯ãæ¢åã®åããåçã«æ°ããåãå€æãæ¡åŒµãæŽŸçãããããšãå¯èœã«ãããã¯ããã¯ã§ãããããã®æ©èœã«ãããTypeScriptã¯åãªãåãã§ãã¯ãè¶ ãããã°ãã°ãåã¬ãã«ããã°ã©ãã³ã°ããšåŒã°ããé åãžãšç§»è¡ããŸãã
ãã®å æ¬çãªã¬ã€ãã§ã¯ãé«åºŠãªå倿ãã¯ããã¯ã®è€éãªäžçãæ·±ãæãäžããŸãããããã®åŒ·åãªããŒã«ããã³ãŒãããŒã¹ãåäžãããéçºè ã®çç£æ§ãé«ããããŒã ãã©ãã«ããŠããã©ã®ç¹å®ã®ãã¡ã€ã³ã§äœæ¥ããŠããŠãããœãããŠã§ã¢å šäœã®å ç¢æ§ãããã«åŒ·åã§ããããæ¢ããŸããè€éãªããŒã¿æ§é ã®ãªãã¡ã¯ã¿ãªã³ã°ãããæ¡åŒµæ§ã®é«ãã©ã€ãã©ãªã®äœæãŸã§ãåæäœããã¹ã¿ãŒããããšã¯ãã°ããŒãã«ãªéçºç°å¢ã§åè¶æ§ãç®æãçå£ãªTypeScriptéçºè ã«ãšã£ãŠäžå¯æ¬ ãªã¹ãã«ã§ãã
åæäœã®æ¬è³ªïŒãªããããéèŠãªã®ã
åæäœã®æ žå¿ã¯ãæè»ã§é©å¿æ§ã®ããåå®çŸ©ãäœæããããšã«ãããŸããããŒã¹ãšãªãããŒã¿æ§é ããããã¢ããªã±ãŒã·ã§ã³ã®ç°ãªãéšåã§ãããå°ã倿ŽããããŒãžã§ã³ãå¿ èŠã«ãªãã·ããªãªãæ³åããŠã¿ãŠãã ãããäŸãã°ãäžéšã®ããããã£ããªãã·ã§ãã«ã«ããããä»ãèªã¿åãå°çšã«ããããããããã£ã®ãµãã»ãããæœåºãããããå¿ èŠãããå Žåã§ããè€æ°ã®åå®çŸ©ãæåã§è€è£œããŠç¶æãã代ããã«ãåæäœã䜿ãã°ãããã®ããªãšãŒã·ã§ã³ãããã°ã©ã ã§çæã§ããŸãããã®ã¢ãããŒãã«ã¯ãããã€ãã®å€§ããªå©ç¹ããããŸãïŒ
- ãã€ã©ãŒãã¬ãŒãã®åæžïŒ å埩çãªåå®çŸ©ã®èšè¿°ãé¿ããŸããåäžã®ããŒã¹åããå€ãã®æŽŸçåãçæã§ããŸãã
- ä¿å®æ§ã®åäžïŒ ããŒã¹åãžã®å€æŽããã¹ãŠã®æŽŸçåã«èªåçã«äŒæãããããå€§èŠæš¡ãªã³ãŒãããŒã¹å šäœã§äžæŽåããšã©ãŒã®ãªã¹ã¯ãæžå°ããŸããããã¯ãã³ãã¥ãã±ãŒã·ã§ã³äžè¶³ãåå®çŸ©ã®ä¹é¢ã«ã€ãªãããããªãã°ããŒãã«ã«åæ£ããããŒã ã«ãšã£ãŠç¹ã«éèŠã§ãã
- åå®å šæ§ã®åäžïŒ åãäœç³»çã«æŽŸçãããããšã§ãã¢ããªã±ãŒã·ã§ã³å šäœã§ããé«åºŠãªåã®æ£ç¢ºæ§ã確ä¿ããæœåšçãªãã°ãå®è¡æã§ã¯ãªãã³ã³ãã€ã«æã«ææããŸãã
- æè»æ§ãšæ¡åŒµæ§ã®åäžïŒ åå®å šæ§ãç ç²ã«ããããšãªããããŸããŸãªãŠãŒã¹ã±ãŒã¹ã«é«åºŠã«é©å¿ã§ããAPIãã©ã€ãã©ãªãèšèšã§ããŸããããã«ãããäžçäžã®éçºè ãèªä¿¡ãæã£ãŠããªãã®ãœãªã¥ãŒã·ã§ã³ãçµ±åã§ããŸãã
- ããè¯ãéçºè äœéšïŒ ã€ã³ããªãžã§ã³ããªåæšè«ãšèªåè£å®ãããæ£ç¢ºã§åœ¹ç«ã€ããã«ãªããéçºãå éããèªç¥è² è·ã軜æžããŸããããã¯ãã¹ãŠã®éçºè ã«ãšã£ãŠæ®éçãªå©ç¹ã§ãã
åã¬ãã«ããã°ã©ãã³ã°ãããã»ã©å€é©çã«ããé«åºŠãªãã¯ããã¯ãè§£ãæããæ ã«åºãŸãããã
äžæ žãšãªãåå€æã®æ§æèŠçŽ ïŒãŠãŒãã£ãªãã£å
TypeScriptã¯ãäžè¬çãªå倿ã®ããã®åºæ¬çãªããŒã«ãšããŠæ©èœãããçµã¿èŸŒã¿ã®ããŠãŒãã£ãªãã£åãã®ã»ãããæäŸããŠããŸãããããã¯ãç¬èªã®è€éãªå€æãäœæããåã«ãåæäœã®ååãçè§£ããããã®åªããåºçºç¹ã§ãã
1. Partial<T>
ãã®ãŠãŒãã£ãªãã£åã¯ãTã®ãã¹ãŠã®ããããã£ããªãã·ã§ãã«ã«èšå®ããåãæ§ç¯ããŸããæ¢åã®ãªããžã§ã¯ãã®ããããã£ã®ãµãã»ããã衚ãåãäœæããå¿ èŠãããå Žåã«éåžžã«äŸ¿å©ã§ããã¹ãŠã®ãã£ãŒã«ããæäŸãããããã§ã¯ãªãæŽæ°æäœã§ãã䜿çšãããŸãã
äŸïŒ
interface UserProfile { id: string; username: string; email: string; country: string; avatarUrl?: string; }
type PartialUserProfile = Partial<UserProfile>; /* 以äžãšåçïŒ type PartialUserProfile = { id?: string; username?: string; email?: string; country?: string; avatarUrl?: string; }; */
const updateUserData: PartialUserProfile = { email: 'new.email@example.com' }; const newUserData: PartialUserProfile = { username: 'global_user_X', country: 'Germany' };
2. Required<T>
éã«ãRequired<T>ã¯ãTã®ãã¹ãŠã®ããããã£ãå¿ é ã«èšå®ããåãæ§ç¯ããŸãããªãã·ã§ãã«ãªããããã£ãæã€ã€ã³ã¿ãŒãã§ãŒã¹ãããããç¹å®ã®ã³ã³ããã¹ãã§ã¯ãããã®ããããã£ãåžžã«ååšããããšãããã£ãŠããå Žåã«äŸ¿å©ã§ãã
äŸïŒ
interface Configuration { timeout?: number; retries?: number; apiKey: string; }
type StrictConfiguration = Required<Configuration>; /* 以äžãšåçïŒ type StrictConfiguration = { timeout: number; retries: number; apiKey: string; }; */
const defaultConfiguration: StrictConfiguration = { timeout: 5000, retries: 3, apiKey: 'XYZ123' };
3. Readonly<T>
ãã®ãŠãŒãã£ãªãã£åã¯ãTã®ãã¹ãŠã®ããããã£ãèªã¿åãå°çšã«èšå®ããåãæ§ç¯ããŸããããã¯ãäžå€æ§ãä¿èšŒããã®ã«éåžžã«äŸ¡å€ããããç¹ã«å ã®ãªããžã§ã¯ãã倿Žãã¹ãã§ãªã颿°ã«ããŒã¿ãæž¡ãå Žåããç¶æ 管çã·ã¹ãã ãèšèšããå Žåã«åœ¹ç«ã¡ãŸãã
äŸïŒ
interface Product { id: string; name: string; price: number; }
type ImmutableProduct = Readonly<Product>; /* 以äžãšåçïŒ type ImmutableProduct = { readonly id: string; readonly name: string; readonly price: number; }; */
const catalogItem: ImmutableProduct = { id: 'P001', name: 'Global Widget', price: 99.99 }; // catalogItem.name = 'New Name'; // ãšã©ãŒïŒ'name'ã¯èªã¿åãå°çšããããã£ã®ãããä»£å ¥ã§ããŸããã
4. Pick<T, K>
Pick<T, K>ã¯ãTããããããã£ã®ã»ããKïŒæååãªãã©ã«ã®ãŠããªã³ïŒãéžæããŠåãæ§ç¯ããŸãã倧ããªåããããããã£ã®ãµãã»ãããæœåºããã®ã«æé©ã§ãã
äŸïŒ
interface Employee { id: string; name: string; department: string; salary: number; email: string; }
type EmployeeOverview = Pick<Employee, 'name' | 'department' | 'email'>; /* 以äžãšåçïŒ type EmployeeOverview = { name: string; department: string; email: string; }; */
const hrView: EmployeeOverview = { name: 'Javier Garcia', department: 'Human Resources', email: 'javier.g@globalcorp.com' };
5. Omit<T, K>
Omit<T, K>ã¯ãTãããã¹ãŠã®ããããã£ãéžæããããããKïŒæååãªãã©ã«ã®ãŠããªã³ïŒãåé€ããŠåãæ§ç¯ããŸããããã¯Pick<T, K>ã®éã§ãããç¹å®ã®ããããã£ãé€å€ããæŽŸçåãäœæããã®ã«åæ§ã«äŸ¿å©ã§ãã
äŸïŒ
interface Employee { /* äžèšãšåã */ }
type EmployeePublicProfile = Omit<Employee, 'salary' | 'id'>; /* 以äžãšåçïŒ type EmployeePublicProfile = { name: string; department: string; email: string; }; */
const publicInfo: EmployeePublicProfile = { name: 'Javier Garcia', department: 'Human Resources', email: 'javier.g@globalcorp.com' };
6. Exclude<T, U>
Exclude<T, U>ã¯ãTããUã«å²ãåœãŠå¯èœãªãã¹ãŠã®ãŠããªã³ã¡ã³ããŒãé€å€ããŠåãæ§ç¯ããŸããããã¯äž»ã«ãŠããªã³åã«å¯ŸããŠäœ¿çšãããŸãã
äŸïŒ
type EventStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled'; type ActiveStatus = Exclude<EventStatus, 'completed' | 'failed' | 'cancelled'>; /* 以äžãšåçïŒ type ActiveStatus = "pending" | "processing"; */
7. Extract<T, U>
Extract<T, U>ã¯ãTããUã«å²ãåœãŠå¯èœãªãã¹ãŠã®ãŠããªã³ã¡ã³ããŒãæœåºããŠåãæ§ç¯ããŸããããã¯Exclude<T, U>ã®éã§ãã
äŸïŒ
type AllDataTypes = string | number | boolean | string[] | { key: string }; type ObjectTypes = Extract<AllDataTypes, object>; /* 以äžãšåçïŒ type ObjectTypes = string[] | { key: string }; */
8. NonNullable<T>
NonNullable<T>ã¯ãTããnullãšundefinedãé€å€ããŠåãæ§ç¯ããŸããnullãundefinedã®å€ãæåŸ ãããªãåãå³å¯ã«å®çŸ©ããã®ã«äŸ¿å©ã§ãã
äŸïŒ
type NullableString = string | null | undefined; type CleanString = NonNullable<NullableString>; /* 以äžãšåçïŒ type CleanString = string; */
9. Record<K, T>
Record<K, T>ã¯ãããããã£ããŒãKã§ãããããã£å€ãTã§ãããªããžã§ã¯ãåãæ§ç¯ããŸããèŸæžã®ãããªåãäœæããã®ã«åŒ·åã§ãã
äŸïŒ
type Countries = 'USA' | 'Japan' | 'Brazil' | 'Kenya'; type CurrencyMapping = Record<Countries, string>; /* 以äžãšåçïŒ type CurrencyMapping = { USA: string; Japan: string; Brazil: string; Kenya: string; }; */
const countryCurrencies: CurrencyMapping = { USA: 'USD', Japan: 'JPY', Brazil: 'BRL', Kenya: 'KES' };
ãããã®ãŠãŒãã£ãªãã£åã¯åºç€ãšãªããŸãããããã¯ãå®çŸ©æžã¿ã®ã«ãŒã«ã«åºã¥ããŠäžã€ã®åãå¥ã®åã«å€æãããšããæŠå¿µã瀺ããŠããŸããæ¬¡ã«ããã®ãããªã«ãŒã«ãèªåã§æ§ç¯ããæ¹æ³ãæ¢ããŸãã
æ¡ä»¶ä»ãåïŒåã¬ãã«ã§ã®ãIf-Elseãã®å
æ¡ä»¶ä»ãåã䜿çšãããšãæ¡ä»¶ã«äŸåããåãå®çŸ©ã§ããŸãããããã¯JavaScriptã®æ¡ä»¶ïŒäžé ïŒæŒç®åïŒcondition ? trueExpression : falseExpressionïŒã«äŒŒãŠããŸãããåã«å¯ŸããŠæäœããŸããæ§æã¯T extends U ? X : Yã§ãã
ããã¯ãããåTãåUã«å²ãåœãŠå¯èœã§ããã°ãçµæã®åã¯Xã«ãªããããã§ãªããã°Yã«ãªãããšãæå³ããŸãã
æ¡ä»¶ä»ãåã¯ãåã·ã¹ãã ã«ããžãã¯ãå°å ¥ãããããé«åºŠãªåæäœã«ãããŠæã匷åãªæ©èœã®äžã€ã§ãã
åºæ¬çãªäŸïŒ
ç°¡ç¥åãããNonNullableãåå®è£ ããŠã¿ãŸãããïŒ
type MyNonNullable<T> = T extends null | undefined ? never : T;
type Result1 = MyNonNullable<string | null>; // string type Result2 = MyNonNullable<number | undefined>; // number type Result3 = MyNonNullable<boolean>; // boolean
ããã§ãããTãnullãŸãã¯undefinedã§ããã°ãããã¯é€å»ãããŸãïŒãŠããªã³åãã广çã«é€å»ãããneverã§è¡šçŸãããŸãïŒãããã§ãªããã°ãTã¯ãã®ãŸãŸæ®ããŸãã
åé çãªæ¡ä»¶ä»ãåïŒ
æ¡ä»¶ä»ãåã®éèŠãªåäœã¯ããŠããªã³åã«å¯Ÿããåé æ§ã§ããæ¡ä»¶ä»ãåã裞ã®åãã©ã¡ãŒã¿ïŒä»ã®åã§ã©ãããããŠããªãåãã©ã¡ãŒã¿ïŒã«å¯ŸããŠäœçšããå Žåãããã¯ãŠããªã³ã®åã¡ã³ããŒã«åé ãããŸããããã¯ãæ¡ä»¶ä»ãåããŠããªã³ã®åã¡ã³ããŒã«åå¥ã«é©çšããããã®çµæãæ°ãããŠããªã³ã«çµåãããããšãæå³ããŸãã
åé æ§ã®äŸïŒ
åãæååãæ°å€ãããã§ãã¯ããåãèããŠã¿ãŸãããïŒ
type IsStringOrNumber<T> = T extends string | number ? 'stringOrNumber' : 'other';
type Test1 = IsStringOrNumber<string>; // "stringOrNumber" type Test2 = IsStringOrNumber<boolean>; // "other" type Test3 = IsStringOrNumber<string | boolean>; // "stringOrNumber" | "other"ïŒåé ãããããïŒ
åé æ§ããªããã°ãTest3ã¯string | booleanãstring | numberã«å®å šã«extendsãããã©ããããã§ãã¯ãïŒããŸããïŒãçµæãšããŠ`"other"`ã«ãªãå¯èœæ§ããããŸããããããåé ããããããstring extends string | number ? ... : ...ãšboolean extends string | number ? ... : ...ãå¥ã ã«è©äŸ¡ãããã®çµæããŠããªã³ããŸãã
å®è·µçãªå¿çšïŒåãŠããªã³ã®å¹³åŠå
ãªããžã§ã¯ãã®ãŠããªã³ããããå ±éã®ããããã£ãæœåºããããç¹å®ã®æ¹æ³ã§ããŒãžãããããããšããŸããæ¡ä»¶ä»ãåãéµãšãªããŸãã
type Flatten<T> = T extends infer R ? { [K in keyof R]: R[K] } : never;
ãã®åçŽãªFlattenã¯ããèªäœã§ã¯ããŸãæå³ããããŸããããæ¡ä»¶ä»ãåãåé æ§ã®ãããªã¬ãŒããšããŠã©ã®ããã«äœ¿çšã§ãããã瀺ããŠããŸããç¹ã«ã次ã«èª¬æããinferããŒã¯ãŒããšçµã¿åãããå Žåã«é¡èã§ãã
æ¡ä»¶ä»ãåã¯ãæŽç·Žãããåã¬ãã«ã®ããžãã¯ãå¯èœã«ããé«åºŠãªå倿ã®åºç€ãšãªããŸãããããã¯ãã°ãã°ä»ã®ãã¯ããã¯ãç¹ã«inferããŒã¯ãŒããšçµã¿åãããŠäœ¿çšãããŸãã
æ¡ä»¶ä»ãåã«ãããæšè«ïŒ'infer'ããŒã¯ãŒã
inferããŒã¯ãŒãã䜿çšãããšãæ¡ä»¶ä»ãåã®extendså¥å ã§å倿°ã宣èšã§ããŸãããã®å€æ°ã¯ããããã³ã°ãããŠããåãããã£ããã£ãããããã«äœ¿çšã§ããæ¡ä»¶ä»ãåã®çã®åå²ã§å©çšå¯èœã«ãªããŸããããã¯åã«å¯Ÿãããã¿ãŒã³ãããã³ã°ã®ãããªãã®ã§ãã
æ§æïŒ T extends SomeType<infer U> ? U : FallbackType;
ããã¯ãåãåè§£ãããã®ç¹å®ã®éšåãæœåºããã®ã«éåžžã«åŒ·åã§ãããã®ã¡ã«ããºã ãçè§£ããããã«ãinferã䜿ã£ãŠåå®è£ ãããããã€ãã®äžæ žçãªãŠãŒãã£ãªãã£åãèŠãŠã¿ãŸãããã
1. ReturnType<T>
ãã®ãŠãŒãã£ãªãã£åã¯ã颿°åã®æ»ãå€ã®åãæœåºããŸããã°ããŒãã«ãªãŠãŒãã£ãªãã£é¢æ°ã®ã»ããããããããããåŒã³åºãããšãªããããããçæããããŒã¿ã®æ£ç¢ºãªåãç¥ãå¿ èŠããããšæ³åããŠã¿ãŠãã ããã
å ¬åŒå®è£ ïŒç°¡ç¥çïŒïŒ
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
äŸïŒ
function getUserData(userId: string): { id: string; name: string; email: string } { return { id: userId, name: 'John Doe', email: 'john.doe@example.com' }; }
type UserDataType = MyReturnType<typeof getUserData>; /* 以äžãšåçïŒ type UserDataType = { id: string; name: string; email: string; }; */
2. Parameters<T>
ãã®ãŠãŒãã£ãªãã£åã¯ã颿°åã®ãã©ã¡ãŒã¿åãã¿ãã«ãšããŠæœåºããŸããåå®å šãªã©ãããŒããã³ã¬ãŒã¿ãäœæããã®ã«äžå¯æ¬ ã§ãã
å ¬åŒå®è£ ïŒç°¡ç¥çïŒïŒ
type MyParameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
äŸïŒ
function sendNotification(userId: string, message: string, priority: 'low' | 'medium' | 'high'): boolean { console.log(`Sending notification to ${userId}: ${message} with priority ${priority}`); return true; }
type NotificationArgs = MyParameters<typeof sendNotification>; /* 以äžãšåçïŒ type NotificationArgs = [userId: string, message: string, priority: 'low' | 'medium' | 'high']; */
3. UnpackPromise<T>
ããã¯ãéåææäœãæ±ãããã®äžè¬çãªã«ã¹ã¿ã ãŠãŒãã£ãªãã£åã§ããPromiseãã解決ãããå€ã®åãæœåºããŸãã
type UnpackPromise<T> = T extends Promise<infer U> ? U : T;
äŸïŒ
async function fetchConfig(): Promise<{ apiBaseUrl: string; timeout: number }> { return { apiBaseUrl: 'https://api.globalapp.com', timeout: 60000 }; }
type ConfigType = UnpackPromise<ReturnType<typeof fetchConfig>>; /* 以äžãšåçïŒ type ConfigType = { apiBaseUrl: string; timeout: number; }; */
inferããŒã¯ãŒãã¯ãæ¡ä»¶ä»ãåãšçµã¿åãããããšã§ãè€éãªåã®éšåãå çãæœåºããã¡ã«ããºã ãæäŸããå€ãã®é«åºŠãªå倿ã®åºç€ã圢æããŸãã
ãããåïŒãªããžã§ã¯ãã®åœ¢ç¶ãäœç³»çã«å€æãã
ãããåã¯ãæ¢åã®ãªããžã§ã¯ãåã®ããããã£ã倿ããŠæ°ãããªããžã§ã¯ãåãäœæããããã®åŒ·åãªæ©èœã§ããäžããããåã®ããŒãå埩åŠçããåããããã£ã«å€æãé©çšããŸããæ§æã¯äžè¬çã«[P in K]: T[P]ã®ããã«ãªããããã§Kã¯éåžžkeyof Tã§ãã
åºæ¬æ§æïŒ
type MyMappedType<T> = { [P in keyof T]: T[P]; // ããã§ã¯å®éã®å€æã¯ãªããããããã£ãã³ããŒããã ã };
ãããåºæ¬çãªæ§é ã§ããéæ³ã¯ããã©ã±ããå ã§ããããã£ãŸãã¯å€ã®åã倿Žãããšãã«èµ·ãããŸãã
äŸïŒ`Readonly
type MyReadonly<T> = { readonly [P in keyof T]: T[P]; };
äŸïŒ`Partial
type MyPartial<T> = { [P in keyof T]?: T[P]; };
P in keyof Tã®åŸã®?ã¯ãããããã£ããªãã·ã§ãã«ã«ããŸããåæ§ã«ã-[P in keyof T]?: T[P]ã§ãªãã·ã§ãã«æ§ãé€å»ãã-readonly [P in keyof T]: T[P]ã§èªã¿åãå°çšãé€å»ã§ããŸãã
'as'å¥ã«ããããŒã®åãããã³ã°ïŒ
TypeScript 4.1ã§ã¯ããããåã«aså¥ãå°å ¥ãããããããã£ããŒãåãããã³ã°ã§ããããã«ãªããŸãããããã¯ãããããã£åã«æ¥é èŸ/æ¥å°ŸèŸã远å ãããã倧æå/å°æåã倿ŽããããããŒããã£ã«ã¿ãªã³ã°ããããããªã©ãããããã£åã倿ããã®ã«éåžžã«äŸ¿å©ã§ãã
æ§æïŒ [P in K as NewKeyType]: T[P];
äŸïŒãã¹ãŠã®ããŒã«æ¥é èŸã远å ãã
type EventPayload = { userId: string; action: string; timestamp: number; };
type PrefixedPayload<T> = { [K in keyof T as `event${Capitalize<string & K>}`]: T[K]; };
type TrackedEvent = PrefixedPayload<EventPayload>; /* 以äžãšåçïŒ type TrackedEvent = { eventUserId: string; eventAction: string; eventTimestamp: number; }; */
ããã§ãCapitalize<string & K>ã¯ãããŒã®æåã®æåã倧æåã«ãããã³ãã¬ãŒããªãã©ã«åïŒæ¬¡ã«èª¬æïŒã§ããstring & Kã¯ãKãCapitalizeãŠãŒãã£ãªãã£ã®ããã«æååãªãã©ã«ãšããŠæ±ãããããšãä¿èšŒããŸãã
ãããã³ã°äžã®ããããã£ã®ãã£ã«ã¿ãªã³ã°ïŒ
aså¥å ã§æ¡ä»¶ä»ãåã䜿çšããŠãããããã£ããã£ã«ã¿ãªã³ã°ããããæ¡ä»¶ä»ãã§ååã倿Žãããããããšãã§ããŸããæ¡ä»¶ä»ãåãneverã«è§£æ±ºããããšããã®ããããã£ã¯æ°ããåããé€å€ãããŸãã
äŸïŒç¹å®ã®åã®ããããã£ãé€å€ãã
type Config = { appName: string; version: number; debugMode: boolean; apiEndpoint: string; };
type StringProperties<T> = { [K in keyof T as T[K] extends string ? K : never]: T[K]; };
type AppStringConfig = StringProperties<Config>; /* 以äžãšåçïŒ type AppStringConfig = { appName: string; apiEndpoint: string; }; */
ãããåã¯ããªããžã§ã¯ãã®åœ¢ç¶ã倿ããã®ã«éåžžã«å€çšéã§ãããããã¯ç°ãªãå°åããã©ãããã©ãŒã ã«ãŸãããããŒã¿åŠçãAPIèšèšãã³ã³ããŒãã³ãã®ããããã£ç®¡çã«ãããŠäžè¬çãªèŠä»¶ã§ãã
ãã³ãã¬ãŒããªãã©ã«åïŒåã®ããã®æååæäœ
TypeScript 4.1ã§å°å ¥ããããã³ãã¬ãŒããªãã©ã«åã¯ãJavaScriptã®ãã³ãã¬ãŒãæååãªãã©ã«ã®åãåã·ã¹ãã ã«ãããããŸããããã«ãããæååãªãã©ã«ããŠããªã³åãä»ã®æååãªãã©ã«åãšé£çµããŠãæ°ããæååãªãã©ã«åãæ§ç¯ã§ããŸãããã®æ©èœã¯ãç¹å®ã®æååãã¿ãŒã³ã«åºã¥ããåãäœæããããã®åºç¯ãªå¯èœæ§ãéããŸãã
æ§æïŒ JavaScriptã®ãã³ãã¬ãŒããªãã©ã«ãšåæ§ã«ãããã¯ã¯ã©ãŒãïŒ`ïŒã䜿çšããããã¬ãŒã¹ãã«ããŒïŒ${Type}ïŒå ã«åãåã蟌ã¿ãŸãã
äŸïŒåºæ¬çãªé£çµ
type Greeting = 'Hello'; type Name = 'World' | 'Universe'; type FullGreeting = `${Greeting} ${Name}!`; /* 以äžãšåçïŒ type FullGreeting = "Hello World!" | "Hello Universe!"; */
ããã¯ãæ¢åã®æååãªãã©ã«åã«åºã¥ããŠæååãªãã©ã«ã®ãŠããªã³åãçæããã®ã«ãã§ã«éåžžã«åŒ·åã§ãã
çµã¿èŸŒã¿ã®æååæäœãŠãŒãã£ãªãã£åïŒ
TypeScriptã¯ãŸããäžè¬çãªæåå倿ã®ããã«ãã³ãã¬ãŒããªãã©ã«åãæŽ»çšãã4ã€ã®çµã¿èŸŒã¿ãŠãŒãã£ãªãã£åãæäŸããŠããŸãïŒ
- Capitalize<S>ïŒ æååãªãã©ã«åã®æåã®æåã倧æåã«å€æããŸãã
- Lowercase<S>ïŒ æååãªãã©ã«åã®åæåãå°æåã«å€æããŸãã
- Uppercase<S>ïŒ æååãªãã©ã«åã®åæåã倧æåã«å€æããŸãã
- Uncapitalize<S>ïŒ æååãªãã©ã«åã®æåã®æåãå°æåã«å€æããŸãã
䜿çšäŸïŒ
type Locale = 'en-US' | 'fr-CA' | 'ja-JP'; type EventAction = 'click' | 'hover' | 'submit';
type EventID = `${Uppercase<EventAction>}_${Capitalize<Locale>}`; /* 以äžãšåçïŒ type EventID = "CLICK_En-US" | "CLICK_Fr-CA" | "CLICK_Ja-JP" | "HOVER_En-US" | "HOVER_Fr-CA" | "HOVER_Ja-JP" | "SUBMIT_En-US" | "SUBMIT_Fr-CA" | "SUBMIT_Ja-JP"; */
ããã¯ãåœéåãããã€ãã³ãIDãAPIãšã³ããã€ã³ãããŸãã¯CSSã¯ã©ã¹åãªã©ã®è€éãªæååãªãã©ã«ã®ãŠããªã³ãåå®å šãªæ¹æ³ã§çæããæ¹æ³ã瀺ããŠããŸãã
ãããåãšã®çµã¿åããã«ããåçãªããŒïŒ
ãã³ãã¬ãŒããªãã©ã«åã®çã®åã¯ããããåãšããŒã®åãããã³ã°ã®ããã®aså¥ãšçµã¿åããããšãã«ãã°ãã°çºæ®ãããŸãã
äŸïŒãªããžã§ã¯ãã®Getter/Setteråãäœæãã
interface Settings { theme: 'dark' | 'light'; notificationsEnabled: boolean; }
type GetterSetters<T> = { [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]; } & { [K in keyof T as `set${Capitalize<string & K>}`]: (value: T[K]) => void; };
type SettingsAPI = GetterSetters<Settings>; /* 以äžãšåçïŒ type SettingsAPI = { getTheme: () => "dark" | "light"; getNotificationsEnabled: () => boolean; } & { setTheme: (value: "dark" | "light") => void; setNotificationsEnabled: (value: boolean) => void; }; */
ãã®å€æã¯ãããŒã¹ã®Settingsã€ã³ã¿ãŒãã§ãŒã¹ããçŽæ¥ãgetTheme()ãsetTheme('dark')ãªã©ã®ã¡ãœãããæã€æ°ããåãã匷åãªåå®å šæ§ãšãšãã«çæããŸããããã¯ãããã¯ãšã³ãAPIãèšå®ãªããžã§ã¯ãã®ããã®å³å¯ã«åä»ããããã¯ã©ã€ã¢ã³ãã€ã³ã¿ãŒãã§ãŒã¹ãçæããã®ã«éåžžã«äŸ¡å€ããããŸãã
ååž°çãªå倿ïŒãã¹ããããæ§é ã®åŠç
å€ãã®å®äžçã®ããŒã¿æ§é ã¯æ·±ããã¹ããããŠããŸããAPIããè¿ãããè€éãªJSONãªããžã§ã¯ããèšå®ããªãŒããã¹ããããã³ã³ããŒãã³ãã®ããããã£ãªã©ãèããŠã¿ãŠãã ããããããã®æ§é ã«å倿ãé©çšããã«ã¯ããã°ãã°ååž°çãªã¢ãããŒããå¿ èŠã§ããTypeScriptã®åã·ã¹ãã ã¯ååž°ããµããŒãããŠãããèªèº«ãåç §ããåãå®çŸ©ã§ãããããããããæ·±ãã§åãèµ°æ»ã倿Žãã倿ãå¯èœã«ãªããŸãã
ããããåã¬ãã«ã®ååž°ã«ã¯å¶éããããŸããTypeScriptã«ã¯ååž°ã®æ·±ãã®å¶éãããïŒéåžžã¯çŽ50ã¬ãã«ã§ãããå€åããããšããããŸãïŒããããè¶ ãããšç¡éã®åèšç®ãé²ãããã«ãšã©ãŒãçºçããŸãããããã®å¶éã«éããããç¡éã«ãŒãã«é¥ã£ããããªãããã«ãååž°çãªåãæ éã«èšèšããããšãéèŠã§ãã
äŸïŒDeepReadonly<T>
Readonly<T>ã¯ãªããžã§ã¯ãã®çŽæ¥ã®ããããã£ãèªã¿åãå°çšã«ããŸããããã¹ãããããªããžã§ã¯ãã«ãããååž°çã«é©çšããŸãããçã«äžå€ãªæ§é ã®ããã«ã¯ãDeepReadonlyãå¿ èŠã§ãã
type DeepReadonly<T> = T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]>; } : T;
ãããåè§£ããŠã¿ãŸãããïŒ
- T extends object ? ... : T;ïŒããã¯æ¡ä»¶ä»ãåã§ããTããªããžã§ã¯ãïŒãŸãã¯JavaScriptã§ã¯ãªããžã§ã¯ãã§ãããé åïŒã§ãããã©ããããã§ãã¯ããŸãããªããžã§ã¯ãã§ãªãå ŽåïŒã€ãŸããstringãnumberãbooleanãnullãundefinedããŸãã¯é¢æ°ã®ãããªããªããã£ãã§ããå ŽåïŒãããªããã£ãã¯æ¬è³ªçã«äžå€ã§ãããããåã«Tèªäœãè¿ããŸãã
- { readonly [K in keyof T]: DeepReadonly<T[K]>; }ïŒTããªããžã§ã¯ãã§ããå Žåããããåãé©çšããŸãã
- readonly [K in keyof T]ïŒTã®åããããã£Kãå埩åŠçãããããreadonlyãšããŠããŒã¯ããŸãã
- DeepReadonly<T[K]>ïŒéèŠãªéšåã§ããåããããã£ã®å€T[K]ã«å¯ŸããŠãååž°çã«DeepReadonlyãåŒã³åºããŸããããã«ãããT[K]èªäœããªããžã§ã¯ãã§ããå Žåãããã»ã¹ãç¹°ãè¿ããããã®ãã¹ããããããããã£ãèªã¿åãå°çšã«ãªããŸãã
䜿çšäŸïŒ
interface UserSettings { theme: 'dark' | 'light'; notifications: { email: boolean; sms: boolean; }; preferences: string[]; }
type ImmutableUserSettings = DeepReadonly<UserSettings>; /* 以äžãšåçïŒ type ImmutableUserSettings = { readonly theme: "dark" | "light"; readonly notifications: { readonly email: boolean; readonly sms: boolean; }; readonly preferences: readonly string[]; // é åã®èŠçŽ ã¯èªã¿åãå°çšã§ã¯ãªãããé åèªäœã¯èªã¿åãå°çšã }; */
const userConfig: ImmutableUserSettings = { theme: 'dark', notifications: { email: true, sms: false }, preferences: ['darkMode', 'notifications'] };
// userConfig.theme = 'light'; // ãšã©ãŒïŒ // userConfig.notifications.email = false; // ãšã©ãŒïŒ // userConfig.preferences.push('locale'); // ãšã©ãŒïŒïŒé ååç §ã«å¯ŸããŠã§ããããã®èŠçŽ ã«å¯ŸããŠã§ã¯ãªãïŒ
äŸïŒDeepPartial<T>
DeepReadonlyãšåæ§ã«ãDeepPartialã¯ãã¹ãããããªããžã§ã¯ãã®ããããã£ãå«ããã¹ãŠã®ããããã£ããªãã·ã§ãã«ã«ããŸãã
type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]>; } : T;
䜿çšäŸïŒ
interface PaymentDetails { card: { number: string; expiry: string; }; billingAddress: { street: string; city: string; zip: string; country: string; }; }
type PaymentUpdate = DeepPartial<PaymentDetails>; /* 以äžãšåçïŒ type PaymentUpdate = { card?: { number?: string; expiry?: string; }; billingAddress?: { street?: string; city?: string; zip?: string; country?: string; }; }; */
const updateAddress: PaymentUpdate = { billingAddress: { country: 'Canada', zip: 'A1B 2C3' } };
ååž°çãªåã¯ããšã³ã¿ãŒãã©ã€ãºã¢ããªã±ãŒã·ã§ã³ãAPIãã€ããŒããã°ããŒãã«ã·ã¹ãã ã®èšå®ç®¡çã§äžè¬çãªãè€éã§éå±€çãªããŒã¿ã¢ãã«ãæ±ãããã«äžå¯æ¬ ã§ãããæ·±ãæ§é ã«ãããéšåçãªæŽæ°ãäžå€ã®ç¶æ ã«å¯ŸããŠæ£ç¢ºãªåå®çŸ©ãå¯èœã«ããŸãã
åã¬ãŒããšã¢ãµãŒã·ã§ã³é¢æ°ïŒå®è¡æã®åã®çµã蟌ã¿
åæäœã¯äž»ã«ã³ã³ãã€ã«æã«è¡ãããŸãããTypeScriptã¯å®è¡æã«åãçµã蟌ãããã®ã¡ã«ããºã ãæäŸããŠããŸãïŒåã¬ãŒããšã¢ãµãŒã·ã§ã³é¢æ°ã§ãããããã®æ©èœã¯ãéçãªåãã§ãã¯ãšåçãªJavaScriptã®å®è¡ãšã®éã®ã®ã£ãããåããå®è¡æã®ãã§ãã¯ã«åºã¥ããŠåãçµã蟌ãããšãå¯èœã«ããŸããããã¯ãã°ããŒãã«ãªæ§ã ãªãœãŒã¹ããã®å€æ§ãªå ¥åããŒã¿ãæ±ãäžã§éåžžã«éèŠã§ãã
åã¬ãŒãïŒè¿°èªé¢æ°ïŒ
åã¬ãŒãã¯ãããŒã«å€ãè¿ãããã®æ»ãå€ã®åãåè¿°èªã§ãã颿°ã§ããåè¿°èªã¯parameterName is Typeãšãã圢åŒãåããŸããTypeScriptãåã¬ãŒããåŒã³åºãããã®ãèŠããšããã®çµæã䜿çšããŠãã®ã¹ã³ãŒãå ã®å€æ°ã®åãçµã蟌ã¿ãŸãã
äŸïŒå€å¥å¯èœãªãŠããªã³å
interface SuccessResponse { status: 'success'; data: any; } interface ErrorResponse { status: 'error'; message: string; code: number; } type ApiResponse = SuccessResponse | ErrorResponse;
function isSuccessResponse(response: ApiResponse): response is SuccessResponse { return response.status === 'success'; }
function handleResponse(response: ApiResponse) { if (isSuccessResponse(response)) { console.log('Data received:', response.data); // 'response'ã¯ããã§SuccessResponseã§ããããšãããã } else { console.error('Error occurred:', response.message, 'Code:', response.code); // 'response'ã¯ããã§ErrorResponseã§ããããšãããã } }
åã¬ãŒãã¯ããŠããªã³åãå®å šã«æ±ãããã«åºæ¬ã§ãããç¹ã«æåã倱æãããŸãã¯ã°ããŒãã«ãªã€ãã³ããã¹å ã®ç°ãªãã¡ãã»ãŒãžã¿ã€ãã«åºã¥ããŠç°ãªãæ§é ãè¿ãå¯èœæ§ã®ããAPIãªã©ã®å€éšãœãŒã¹ããã®ããŒã¿ãåŠçããå Žåã«éèŠã§ãã
ã¢ãµãŒã·ã§ã³é¢æ°
TypeScript 3.7ã§å°å ¥ãããã¢ãµãŒã·ã§ã³é¢æ°ã¯ãåã¬ãŒãã«äŒŒãŠããŸãããç®çãç°ãªããŸããæ¡ä»¶ãçã§ããããšã衚æããããã§ãªããã°ãšã©ãŒãã¹ããŒããããšã§ãããã®æ»ãå€ã®åã¯asserts conditionæ§æã䜿çšããŸããassertsã·ã°ããã£ãæã€é¢æ°ãã¹ããŒããã«è¿ããšãTypeScriptã¯è¡šæã«åºã¥ããŠåŒæ°ã®åãçµã蟌ã¿ãŸãã
äŸïŒénullæ§ã衚æãã
function assertIsDefined<T>(val: T, message?: string): asserts val is NonNullable<T> { if (val === undefined || val === null) { throw new Error(message || 'Value must be defined'); } }
function processConfig(config: { baseUrl?: string; retries?: number }) { assertIsDefined(config.baseUrl, 'Base URL is required for configuration'); // ãã®è¡ã®åŸãconfig.baseUrlã¯'string'ã§ããããšãä¿èšŒããã'string | undefined'ã§ã¯ãªã console.log('Processing data from:', config.baseUrl.toUpperCase()); if (config.retries !== undefined) { console.log('Retries:', config.retries); } }
ã¢ãµãŒã·ã§ã³é¢æ°ã¯ãäºåæ¡ä»¶ã®åŒ·å¶ãå ¥åã®æ€èšŒãããã³æäœãç¶è¡ããåã«éèŠãªå€ãååšããããšãä¿èšŒããã®ã«åªããŠããŸããããã¯ãä¿¡é Œæ§ã®äœããœãŒã¹ã倿§ãªã°ããŒãã«ãŠãŒã¶ãŒåãã«èšèšããããŠãŒã¶ãŒå ¥åãã©ãŒã ããã®ããŒã¿ãæ¥ãå¯èœæ§ã®ããå ¥åæ€èšŒã«ãããŠãå ç¢ãªã·ã¹ãã èšèšã§éåžžã«äŸ¡å€ããããŸãã
åã¬ãŒããšã¢ãµãŒã·ã§ã³é¢æ°ã®äž¡æ¹ããTypeScriptã®éçåã·ã¹ãã ã«åçãªèŠçŽ ãæäŸããå®è¡æã®ãã§ãã¯ãã³ã³ãã€ã«æã®åã«æ å ±ãæäŸããããšãå¯èœã«ããããã«ãã£ãŠã³ãŒãå šäœã®å®å šæ§ãšäºæž¬å¯èœæ§ãé«ããŸãã
å®äžçã§ã®å¿çšãšãã¹ããã©ã¯ãã£ã¹
é«åºŠãªå倿ãã¯ããã¯ãç¿åŸããããšã¯ãåãªãåŠè¡çãªæŒç¿ã§ã¯ãããŸãããé«å質ãªãœãããŠã§ã¢ãæ§ç¯ããäžã§ãç¹ã«ã°ããŒãã«ã«åæ£ããéçºããŒã ã«ãããŠãæ·±ãå®è·µçãªæå³ãæã¡ãŸãã
1. å ç¢ãªAPIã¯ã©ã€ã¢ã³ãã®çæ
RESTãGraphQL APIãå©çšããããšãæ³åããŠã¿ãŠãã ãããåãšã³ããã€ã³ãã®ã¬ã¹ãã³ã¹ã€ã³ã¿ãŒãã§ãŒã¹ãæåã§èšè¿°ãã代ããã«ãã³ã¢ãªåãå®çŸ©ãããããåãæ¡ä»¶ä»ãåãinferåã䜿çšããŠããªã¯ãšã¹ããã¬ã¹ãã³ã¹ããšã©ãŒã®ã¯ã©ã€ã¢ã³ããµã€ãã®åãçæã§ããŸããäŸãã°ãGraphQLã¯ãšãªæååãå®å šã«åä»ããããçµæãªããžã§ã¯ãã«å€æããåã¯ãé«åºŠãªåæäœã®åªããå®äŸã§ããããã«ãããããŸããŸãªå°åã«ãããã€ãããç°ãªãã¯ã©ã€ã¢ã³ãããã€ã¯ããµãŒãã¹éã§ã®äžè²«æ§ãä¿èšŒãããŸãã
2. ãã¬ãŒã ã¯ãŒã¯ãšã©ã€ãã©ãªéçº
ReactãVueãAngularãªã©ã®äž»èŠãªãã¬ãŒã ã¯ãŒã¯ããRedux Toolkitãªã©ã®ãŠãŒãã£ãªãã£ã©ã€ãã©ãªã¯ãåªããéçºè äœéšãæäŸããããã«åæäœã«å€§ããäŸåããŠããŸãããããã®ãã¯ããã¯ã䜿çšããŠãããããã£ãç¶æ ãã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒãã»ã¬ã¯ã¿ãŒã®åãæšè«ããéçºè ã匷åãªåå®å šæ§ãç¶æããªãããã€ã©ãŒãã¬ãŒããå°ãªãæžããããã«ããŸãããã®æ¡åŒµæ§ã¯ãã°ããŒãã«ãªéçºè ã³ãã¥ããã£ã«æ¡çšãããã©ã€ãã©ãªã«ãšã£ãŠäžå¯æ¬ ã§ãã
3. ç¶æ 管çãšäžå€æ§
è€éãªç¶æ ãæã€ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãäžå€æ§ã確ä¿ããããšãäºæž¬å¯èœãªæ¯ãèãã®éµã§ããDeepReadonlyåã¯ããããã³ã³ãã€ã«æã«åŒ·å¶ããå¶çºçãªå€æŽãé²ãã®ã«åœ¹ç«ã¡ãŸããåæ§ã«ãç¶æ æŽæ°ã®ããã®æ£ç¢ºãªåãå®çŸ©ããããšïŒäŸãã°ããããæäœã«DeepPartialã䜿çšããïŒã¯ãç¶æ ã®äžè²«æ§ã«é¢é£ãããã°ãå€§å¹ ã«åæžã§ããäžçäžã®ãŠãŒã¶ãŒã«ãµãŒãã¹ãæäŸããã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠäžå¯æ¬ ã§ãã
4. èšå®ç®¡ç
ã¢ããªã±ãŒã·ã§ã³ã¯ãã°ãã°è€éãªèšå®ãªããžã§ã¯ããæã£ãŠããŸããåæäœã¯ãå³å¯ãªèšå®ãå®çŸ©ããããç°å¢åºæã®ãªãŒããŒã©ã€ãïŒéçºç°å¢å¯Ÿæ¬çªç°å¢ã®åãªã©ïŒãé©çšããããã¹ããŒãå®çŸ©ã«åºã¥ããŠèšå®åãçæãããããã®ã«åœ¹ç«ã¡ãŸããããã«ãããç°ãªã倧éžã«ãŸãããå¯èœæ§ã®ããç°ãªããããã€ã¡ã³ãç°å¢ãã峿 Œãªã«ãŒã«ã«æºæ ããèšå®ã䜿çšããããšãä¿èšŒãããŸãã
5. ã€ãã³ãé§åã¢ãŒããã¯ãã£
ã€ãã³ããç°ãªãã³ã³ããŒãã³ãããµãŒãã¹éãæµããã·ã¹ãã ã§ã¯ãæç¢ºãªã€ãã³ãåãå®çŸ©ããããšãæãéèŠã§ãããã³ãã¬ãŒããªãã©ã«åã¯ãäžæã®ã€ãã³ãIDïŒäŸïŒUSER_CREATED_V1ïŒãçæã§ããæ¡ä»¶ä»ãåã¯ç°ãªãã€ãã³ããã€ããŒããåºå¥ããã®ã«åœ¹ç«ã¡ãã·ã¹ãã ã®ççµåãªéšåéã®å ç¢ãªéä¿¡ãä¿èšŒããŸãã
ãã¹ããã©ã¯ãã£ã¹ïŒ
- ã·ã³ãã«ã«å§ããïŒ ããã«æãè€éãªè§£æ±ºçã«é£ã³ã€ããªãã§ãã ãããåºæ¬çãªãŠãŒãã£ãªãã£åããå§ããå¿ èŠãªå Žåã«ã®ã¿è€éããå ããŠãã ããã
- 培åºçã«ææžåããïŒ é«åºŠãªåã¯çè§£ãé£ããããšããããŸããJSDocã³ã¡ã³ãã䜿çšããŠããã®ç®çãæåŸ ãããå ¥åãããã³åºåã説æããŠãã ãããããã¯ãç¹ã«å€æ§ãªèšèªèæ¯ãæã€ããŒã ã«ãšã£ãŠäžå¯æ¬ ã§ãã
- åããã¹ãããïŒ ã¯ããåããã¹ãã§ããŸãïŒtsdïŒTypeScript Definition TesterïŒã®ãããªããŒã«ã䜿çšããããç°¡åãªä»£å ¥ãæžããŠåãæåŸ ã©ããã«åäœããããšã確èªããŠãã ããã
- åå©çšæ§ãåªå ããïŒ ãã®å Žãã®ãã®äžåéãã®åå®çŸ©ã§ã¯ãªããã³ãŒãããŒã¹å šäœã§åå©çšã§ããæ±çšçãªãŠãŒãã£ãªãã£åãäœæããŠãã ããã
- è€éããšæçãã®ãã©ã³ã¹ãåãïŒ åŒ·åã§ããäžæ¹ãé床ã«è€éãªåã®éæ³ã¯ã¡ã³ããã³ã¹ã®è² æ ã«ãªãå¯èœæ§ããããŸããåå®å šæ§ã®å©ç¹ãåå®çŸ©ãçè§£ããããã®èªç¥è² è·ãäžåããã©ã³ã¹ãç®æããŠãã ããã
- ã³ã³ãã€ã«ããã©ãŒãã³ã¹ãç£èŠããïŒ éåžžã«è€éãŸãã¯æ·±ãååž°çãªåã¯ãTypeScriptã®ã³ã³ãã€ã«ãé ãããããšããããŸããããã©ãŒãã³ã¹ã®äœäžã«æ°ä»ããå Žåã¯ãåå®çŸ©ãèŠçŽããŠãã ããã
é«åºŠãªãããã¯ãšå°æ¥ã®æ¹åæ§
åæäœãžã®æ ã¯ããã§çµããã§ã¯ãããŸãããTypeScriptããŒã ã¯ç¶ç¶çã«é©æ°ãç¶ããŠãããã³ãã¥ããã£ã¯ããã«æŽç·ŽãããæŠå¿µãç©æ¥µçã«æ¢æ±ããŠããŸãã
å ¬ç§°çåä»ããšæ§é çåä»ã
TypeScriptã¯æ§é çåä»ãã§ããã2ã€ã®åã宣èšãããååã«é¢ä¿ãªãåã圢ç¶ãæã£ãŠããã°äºææ§ããããšèŠãªãããŸããå¯Ÿç §çã«ãå ¬ç§°çåä»ãïŒC#ãJavaãªã©ã®èšèªã«èŠãããïŒã¯ãåã宣èšãç¶æ¿ãã§ãŒã³ãå ±æããŠããå Žåã«ã®ã¿åãäºææ§ããããšèŠãªããŸããTypeScriptã®æ§é çãªæ§è³ªã¯ãã°ãã°æçã§ãããå ¬ç§°çãªæ¯ãèããæãŸããã·ããªãªããããŸãïŒäŸãã°ãäž¡æ¹ãåãªãstringã§ãã£ãŠããUserIDåãProductIDåã«ä»£å ¥ããã®ãé²ãå Žåãªã©ïŒã
åãã©ã³ãã£ã³ã°æè¡ã¯ãäžæã®ã·ã³ãã«ããããã£ããªãã©ã«ãŠããªã³ã亀差åãšçµã¿åãããŠäœ¿çšããããšã§ãTypeScriptã§å ¬ç§°çåä»ããã·ãã¥ã¬ãŒãã§ããŸããããã¯ãæ§é çã«åäžã§ãããªããæŠå¿µçã«ç°ãªãåã®éã®ãã匷åãªåºå¥ãäœæããããã®é«åºŠãªãã¯ããã¯ã§ãã
äŸïŒç°¡ç¥çïŒïŒ
type Brand<T, B> = T & { __brand: B }; type UserID = Brand<string, 'UserID'>; type ProductID = Brand<string, 'ProductID'>;
function getUser(id: UserID) { /* ... */ } function getProduct(id: ProductID) { /* ... */ }
const myUserId: UserID = 'user-123' as UserID; const myProductId: ProductID = 'prod-456' as ProductID;
getUser(myUserId); // OK // getUser(myProductId); // ãšã©ãŒïŒå 'ProductID' ã¯å 'UserID' ã«å²ãåœãŠãããŸããã
åã¬ãã«ããã°ã©ãã³ã°ã®ãã©ãã€ã
åãããåçã§è¡šçŸåè±ãã«ãªãã«ã€ããŠãéçºè ã¯é¢æ°åããã°ã©ãã³ã°ã圷圿ãšãããåã¬ãã«ã®ããã°ã©ãã³ã°ãã¿ãŒã³ãæ¢æ±ããŠããŸããããã«ã¯ãåã¬ãã«ã®ãªã¹ããã¹ããŒããã·ã³ãããã«ã¯åã·ã¹ãã å ã§å®å šã«æ©èœããåæ©çãªã³ã³ãã€ã©ãªã©ã®ãã¯ããã¯ãå«ãŸããŸããéåžžã®ã¢ããªã±ãŒã·ã§ã³ã³ãŒãã«ã¯é床ã«è€éã§ããããšãå€ãã§ããããããã®æ¢æ±ã¯å¯èœãªããšã®éçãæŒãåºããå°æ¥ã®TypeScriptã®æ©èœã«æ å ±ãæäŸããŸãã
çµè«
TypeScriptã®é«åºŠãªå倿ãã¯ããã¯ã¯ãåãªãã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒã§ã¯ãããŸãããæŽç·Žãããå埩åããããä¿å®æ§ã®é«ããœãããŠã§ã¢ã·ã¹ãã ãæ§ç¯ããããã®åºæ¬çãªããŒã«ã§ããæ¡ä»¶ä»ãåããããåãinferããŒã¯ãŒãããã³ãã¬ãŒããªãã©ã«åãååž°çãªãã¿ãŒã³ãåãå ¥ããããšã§ãããå°ãªãã³ãŒããæžããã³ã³ãã€ã«æã«ããå€ãã®ãšã©ãŒãææããæè»ã§éåžžã«å ç¢ãªAPIãèšèšããåãåŸãããšãã§ããŸãã
ãœãããŠã§ã¢æ¥çãã°ããŒãã«åãç¶ããäžã§ãæç¢ºã§ãææ§ãããªããå®å šãªã³ãŒãæ £è¡ã®å¿ èŠæ§ã¯ããã«éèŠã«ãªããŸããTypeScriptã®é«åºŠãªåã·ã¹ãã ã¯ãããŒã¿æ§é ãšæ¯ãèããå®çŸ©ãã匷å¶ããããã®æ®éçãªèšèªãæäŸãã倿§ãªèæ¯ãæã€ããŒã ã广çã«ååããé«å質ã®è£œåãæäŸã§ããããã«ããŸãããããã®ãã¯ããã¯ãç¿åŸããããã«æéãæè³ããã°ãTypeScriptéçºã®æ ã§æ°ããã¬ãã«ã®çç£æ§ãšèªä¿¡ãè§£ãæŸã€ããšãã§ããã§ãããã
ããªãã®ãããžã§ã¯ãã§æã圹ç«ã£ãé«åºŠãªåæäœã¯äœã§ããïŒä»¥äžã®ã³ã¡ã³ãã§ããªãã®æŽå¯ãäŸãå ±æããŠãã ããïŒ